LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

entity op_de is
 port (
 OP : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
 S : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); -- ALU模式选择
 WE : OUT STD_LOGIC;
 Smux : OUT STD_LOGIC; --1封锁时间信号
 Exop : OUT STD_LOGIC;-- 为0无符号数扩展，1为有符号数扩展
 Imux : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
 str : OUT STD_LOGIC;
 ld : OUT STD_LOGIC;
 Lmux : OUT STD_LOGIC; --读ram或ALU输入寄存器，1为读ram，0为读ALU
 PC_1 : OUT STD_LOGIC; -- incres_pc信号
 wpc : OUT STD_LOGIC;
 beq : OUT STD_LOGIC;
 bne : OUT STD_LOGIC;
 bgt : OUT STD_LOGIC;
 jump : OUT STD_LOGIC; -- pc的跳转信号
 R_type : OUT STD_LOGIC; -- R指令选通信号
 W_rom :OUT STD_LOGIC -- DISP[imm] = $rs ，MEM[$rs+imm] = $rt选择写入rom的数据，为0来自rs，为1来自rt 
 );
END op_de;
ARCHITECTURE behav OF op_de IS
--SIGNAL OP : STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN

 PROCESS(OP)
 BEGIN
	CASE OP(15 DOWNTO 12) IS
		WHEN "0000"=> S<="0000"; WE<='1'; jump<='0'; PC_1<='1'; R_type<='1';  -- pc_1=1表pc+1,R_type=1表示选择R型指令，jump=1表示直接跳转到当前输入地址的指令
		Lmux<='0'; wpc<='0'; beq<='0'; bne<='0'; bgt<='0'; ld<='0';str<='0';Imux<="00";Smux<='0'; Exop<='0'; W_rom<='0'; -- 使用R地址译码器
	
		WHEN "0001"=> S<="1000";WE<='0'; Smux<='0'; Exop<='0'; Imux<="00"; str<='0'; ld<='0'; --9 DISP[0x0001 + imm] = $rs 把rs数据需要存到基址寄存器的地址+imm的地址中
		Lmux<='0'; PC_1<='1';wpc<='0'; beq<='0'; bne<='0'; bgt<='0'; jump<='0'; R_type<='0'; W_rom<='0';

		WHEN "0010"=> S<="1001";WE<='1'; Smux<='0'; Exop<='0'; Imux<="00"; str<='0'; ld<='0'; --10 lui $rt = imm << 8
		Lmux<='0'; PC_1<='1'; wpc<='0'; beq<='0'; bne<='0'; bgt<='0'; jump<='0'; R_type<='0';W_rom<='0';
		
		WHEN "0011"=> S<="0000";WE<='1'; Smux<='0'; Exop<='0'; Imux<="00"; str<='0'; ld<='0'; --11 or $rt = $rs | imm
		Lmux<='0'; PC_1<='1'; wpc<='0'; beq<='0'; bne<='0'; bgt<='0'; jump<='0'; R_type<='0';W_rom<='0';
		
		WHEN "0100"=> S<="0001";WE<='1'; Smux<='0'; Exop<='0'; Imux<="00"; str<='0'; ld<='0'; --12 $rt = $rs & imm
		Lmux<='0'; PC_1<='1'; wpc<='0'; beq<='0'; bne<='0'; bgt<='0'; jump<='0'; R_type<='0';W_rom<='0';
		
		WHEN "0101"=> S<="0010";WE<='1'; Smux<='0'; Exop<='1'; Imux<="00"; str<='0'; ld<='0'; --13 $rt = $rs + imm
		Lmux<='0'; PC_1<='1'; wpc<='0'; beq<='0'; bne<='0'; bgt<='0'; jump<='0'; R_type<='0';W_rom<='0';
		
		WHEN "0110"=> S<="0010";WE<='1'; Smux<='0'; Exop<='1'; Imux<="00"; str<='0'; ld<='0'; --14 $rt = MEM[$rs + imm]
		Lmux<='1'; PC_1<='1'; wpc<='0'; beq<='0'; bne<='0'; bgt<='0'; jump<='0'; R_type<='0';W_rom<='0';
		
		WHEN "0111"=> S<="0010";WE<='0'; Smux<='0'; Exop<='1'; Imux<="00"; str<='0'; ld<='0';-- 15 MEM[$rs+imm] = $rt
		Lmux<='0'; PC_1<='1'; wpc<='0'; beq<='0'; bne<='0'; bgt<='0'; jump<='0'; R_type<='0';W_rom<='1';
		
		wHEN "1000"=> S<="1100";WE<='0'; Smux<='0'; Exop<='0'; Imux<="00"; str<='0'; ld<='0'; --16 jump 
		Lmux<='0'; PC_1<='0'; wpc<='0'; beq<='0'; bne<='0'; bgt<='0'; jump<='1'; R_type<='0';
		
		WHEN "1001"=> S<="1101";WE<='0'; Smux<='1'; Exop<='0'; Imux<="00"; str<='0'; ld<='0'; --17 halt
		Lmux<='0'; PC_1<='0'; wpc<='0'; beq<='0'; bne<='0'; bgt<='0'; jump<='0'; R_type<='0';
		
		WHEN "1100"=> S<="1010";WE<='1'; Smux<='0'; Exop<='0'; Imux<="00"; str<='0'; ld<='0'; --20 load_rs
		Lmux<='0'; PC_1<='1'; wpc<='0'; beq<='0'; bne<='0'; bgt<='0'; jump<='0'; R_type<='0';
		
		WHEN "1101"=> S<="1011";WE<='1'; Smux<='0'; Exop<='0'; Imux<="00"; str<='0'; ld<='0'; --21 load_rt
		Lmux<='0'; PC_1<='1'; wpc<='0'; beq<='0'; bne<='0'; bgt<='0'; jump<='0'; R_type<='0';
		when OTHERS=> S<="0000"; Smux <= '1'; -- 如果输入指令出错直接halt
	END CASE;
 END PROCESS;
END behav;